package ebedynky.controllers;

import ebedynky.beans.*;
import ebedynky.services.*;
import java.util.*;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Ondrej David (davidon1)
 */
@Controller
public class UserController {

    /**
     * Fetches the User adding page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String getCreateForm(Model model) {
        model.addAttribute(new User());
        return "user/user";
    }

    /**
     * Extracts the User data from the form,
     * validates them and stores them into 
     * the db as corresponding user type 
     * (Supplier/Customer/Employee/Administrator).
     * @param user data from the form
     * @param result data binding result
     * @return string representing next (success/failure) page location
     */
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String create(@Valid User user, BindingResult result) {
        if (result.hasErrors()) {
            return "user/user";
        }
        user.setAccountState(false);
        if (user.getRoles().equals("customer")) {
            CustomerService cs = new CustomerService();
            Customer c = new Customer(user);
            cs.addCustomer(c);
        } else if (user.getRoles().equals("supplier")) {
            SupplierService ss = new SupplierService();
            Supplier s = new Supplier(user);
            ss.addSupplier(s);
        } else if (user.getRoles().equals("employee")) {
            EmployeeService es = new EmployeeService();
            Employee e = new Employee(user);
            es.addEmployee(e);
        } else if (user.getRoles().equals("admin")) {
            AdministratorService as = new AdministratorService();
            Administrator a = new Administrator(user);
            as.addAdministrator(a);
        }
        return "/user/success";
    }

    /**
     * Lists all users in the db.
     * @return page location and data
     */
    @RequestMapping(value = "/Allusers", method = RequestMethod.GET)
    public ModelAndView listUser() {
        UserService us = new UserService();
        Map<String, Object> model = new HashMap<String, Object>();
        model.put("users", us.getAllUsers());
        return new ModelAndView("user/Allusers", model);

    }

    /**
     * Deletes the corresponding User data from the db by id.
     * @param id path variable, id of user to be deleted
     * @return string representing next page location
     */
    @RequestMapping(value = "/deleteUser/{id}", method = RequestMethod.GET)
    public String delete(@PathVariable Integer id) {
        UserService us = new UserService();
        User u = us.getUserByID(id);
        if (u.getRoles().equals("customer")) {
            CustomerService cs = new CustomerService();
            cs.deleteCustomer(id.intValue());
        } else if (u.getRoles().equals("supplier")) {
            SupplierService ss = new SupplierService();
            ss.deleteSupplier(id.intValue());
        } else if (u.getRoles().equals("employee")) {
            EmployeeService es = new EmployeeService();
            es.deleteEmployee(id.intValue());
        }
        return "redirect:/Allusers";
    }

    /**
     * Changes account state of a user specified by id to allowed (true).
     * @param id of the user to change account state
     * @return string representing next page location
     */
    @RequestMapping(value = "/allow/{id}", method = RequestMethod.GET)
    public String changeAccoutStateToAllow(@PathVariable Integer id) {
        UserService us = new UserService();
        us.ChangeAccoutStateToAllow(id.intValue());
        return "redirect:/Allusers";
    }

    /**
     * Changes account state of a user specified by id to denied (false).
     * @param id of the user to change account state
     * @return string representing next page location
     */
    @RequestMapping(value = "/deny/{id}", method = RequestMethod.GET)
    public String changeAccoutStateToDeny(@PathVariable Long id) {
        UserService us = new UserService();
        us.ChangeAccoutStateToDeny(id.intValue());
        return "redirect:/Allusers";
    }

    /**
     * Fetches the user finding page when requested.
     * @param model data holder for this view
     * @return string representing page location
     */
    @RequestMapping(value = "/FindUser", method = RequestMethod.GET)
    public String getFindForm(Model model) {
        model.addAttribute(new User());
        return "user/FindUser";
    }

    /**
     * Fetches the found user detail page when requested.
     * @param user the user details to be found
     * @return ModelAndView containing the page location and the data
     */
    @RequestMapping(value = "/find", method = RequestMethod.POST)
    public ModelAndView Find(User user) {
        Map<String, Object> model = new HashMap<String, Object>();
        UserService us = new UserService();
        model.put("users", us.FindUserByParameters(user.getName(), user.getSurname(), user.getEmail(), user.getUsername(), user.getUserID()));
        return new ModelAndView("user/Allusers", model);
    }
}
